package dataImport.action;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import dataImport.action.abstracts.AbstractEntityReader;
import dataImport.action.helper.UnityGuardian;
import dataImport.action.manager.EntityReaderManager;
import dataImport.exception.DuplicateAttributeException;
import dataImport.exception.MissingContentException;
import dataImport.exception.NoEntityRelatedWithException;
import dataImport.exception.UniquenessRestrictionViolatedException;
import dataImport.model.Place;
import dataImport.model.Scenario;
import dataImport.model.State;
import dataImport.model.Text;
import dataImport.model.abstracts.AbstractEntity;


public class ScenarioReader extends AbstractEntityReader {

	private static final long serialVersionUID = 2763408064714520756L;

	public static final String ENTITY_NAME = "scenario";

	private static final String ATTRIBUTE_STATE_ID = "state";

	private final UnityGuardian stateEntityIdUniqueKey;

	public ScenarioReader(final EntityReaderManager entityReaderManager) {
		super(entityReaderManager);
		this.stateEntityIdUniqueKey = new UnityGuardian();
	}

	@Override
	protected AbstractEntity createEntity(final Element element) {
		final String id = element.getAttribute(ATTRIBUTE_ID);
		final String stateId = element.getAttribute(ATTRIBUTE_STATE_ID);
		final String text = element.getTextContent();
		final Element parentNode = (Element) element.getParentNode();
		final String parentNodeName = parentNode.getNodeName();
		final String parentNodeId = parentNode.getAttribute(ATTRIBUTE_ID);

		this.verifyRestrictions(id, stateId, text, parentNodeName, parentNodeId);

		final State state = stateId.isEmpty() ? null : (State) super.getEntityReaderManager().getStateReader().getEntityWithId(stateId);
		final Place place = (Place) super.getEntityReaderManager().getPlaceReader().getEntityWithId(parentNodeId);

		return new Scenario(id, state, new Text(text, super.getEntityReaderManager()), place);
	}

	@Override
	public void read(final Document document) {
		this.read(ScenarioReader.ENTITY_NAME, document);
	}

	protected final void verifyRestrictions(final String id, final String stateId, final String text, final String relatedTo, final String relatedToId) {
		super.verifyRestrictions(id);

		if (!relatedTo.equals(PlaceReader.ENTITY_NAME)) {
			throw new NoEntityRelatedWithException(ScenarioReader.ENTITY_NAME, PlaceReader.ENTITY_NAME);
		}

		if (text.isEmpty()) {
			throw new MissingContentException();
		}

		try {
			this.stateEntityIdUniqueKey.ensureUniqueness(stateId, relatedToId);
		}
		catch (final UniquenessRestrictionViolatedException e) {
			throw new DuplicateAttributeException("state", stateId);
		}
	}
}
